home *** CD-ROM | disk | FTP | other *** search
- /*
- UASM - UNIVERSAL CROSS ASSMEBLER uasm.c
- CUSTOM COMPUTER CONSULTANTS
- 5 April 1986
-
- */
- #include <stdio.h>
- #include <uasm.h>
-
- #define NHASH 512
- #define HP1 7
- #define HP2 2
- /* Flags */
-
- int sf, lf, hf, nolist ;
- int pass1, pass2 ;
- int lbl ;
- int info ;
- int valid ;
-
- /* Numbers */
- int i, j, k ;
- int kk, r ;
- int lineno, lnspp, pgno ;
-
- int cc ; /* character count */
- int mcc ; /* mark character count */
- int ll ; /* line length */
- int maxop ;
- int maxpseudo ;
- int ilc, active ;
- int il[NSEG] ;
- int instl ;
- int parval ;
- int num ;
- int radix ;
- int cput ; /* ib pointer */
- int errcnt, esp ;
- int syte, sytx ;
-
- unsigned unpar ;
- unsigned ht ; /* Record Type */
- unsigned ha ; /* Record Start Address */
- unsigned he ; /* Expected Address of next item */
- unsigned hc ; /* Checksum Mod 256 */
- unsigned hsp ; /* Hex String Pointer */
-
- long start, finish, time() ;
- #define NOW (0L)
- /* Characters */
-
- unsigned char ch ; /* last character */
- unsigned char nch ; /* next character */
- unsigned char sym ; /* last symbol */
- /* Pointers */
-
- char *iptr ; /* Input Buffer */
- char *src ; /* Source File Name */
- char *cp ; /* General Purpose */
-
- /* Character Arrays */
-
- char hex[13] ; /* Hex File Name */
- char lst[13] ; /* List File Name */
-
- char segtype[NSEG] ;
-
- char id[AL] ; /* Last Identifier */
- unsigned char ib[256] ; /* Instruction Byte Queue */
- unsigned char ssym[256] ; /* character symbols */
- unsigned char hs[MAXB] ;
- char errstk[25] ;
- unsigned char pv[200] ;
- unsigned char px[80] ;
-
- int pj[15] ;
-
- int qhash[NHASH] ; /* Head indexes for hash chains */
- int nlook, nprobe ;
- int maxprobe ;
-
- /* Pointer Arrays */
-
- char *pc[80], *pseudo[15] ;
-
- int (*pp[200])() ;
- int (*ppo[15])() ;
- /* I/O Buffers */
-
- char ibuf[MAXLINE] ;
- FILE *dibuf, *libuf, *hxbuf ;
-
- struct symbol symtab[NSYM] ;
- int psym[NSYM] ;
-
- extern char push() ;
- extern char pop() ;
- extern int cpmf() ;
- extern char *strcat() ;
-
-
- extern char *version ;
-
- /*
- Control Programs
-
- main() Open files, assemble, close files, exit
- assemble() Process input and create tables
- code() Generate object output
- list() Generate Listing
- */
-
- main(narg,argv)
- int narg;
- char **argv;
-
- {
- start = time(NOW) ;
-
- puts("\033[2J") ; /* CLEAR_SCREEN */
-
- puts("Universal Cross Assembler -- V1.4 4/5/86\n") ;
- puts("(c) Custom Computer Consultants, 1986\n") ;
- puts(version) ;
-
- sf = lf = hf = nolist = FALSE ;
-
- /* FILE OPERATIONS */
-
- if( --narg > 0 ) {
- dibuf = fopen( *(++argv), "r" ) ;
- if( dibuf == NULL ) abort("Source ?\n") ;
- src = *argv ; sf = TRUE ;
- }
-
- if( --narg > 0 ) {
- j = 0 ;
- while( **argv != '.' && j < 8 ) {
- hex[j] = lst[j] = *(*argv)++ ;
- ++j ;
- }
- hex[j] = lst[j] = EOS ;
- strcat( hex, ".HEX" ) ;
- strcat( lst, ".LST" ) ;
- ++argv ;
- while( ch = *(*argv)++ ) {
- if((ch == 'L') || (ch == 'l')) {
- libuf = fopen(lst,"w") ;
- if( libuf == NULL ) abort("List ?\n") ;
- lf = TRUE ;
- }
- else if((ch == 'O') || (ch == 'o')) {
- hxbuf = fopen(hex,"w") ;
- if( hxbuf == NULL ) abort("Hex ?\n") ;
- hf = TRUE ;
- }
- else if((ch == 'N') || (ch == 'n')) nolist = TRUE ;
-
- } /* END while(ch = *(*argv)++ ) */
-
- } /* END if(--narg > 0) */
-
- syte = pgno = lnspp = 0 ;
- nlook = nprobe = maxprobe = 0 ;
- setmem(ssym,256,NUL) ; /* NUL is the token value \200 */
- setmem(qhash,2*NHASH,ERROR) ;
-
- cp = "$+-*/(),;%~|&^'@#.<>\"" ;
- while( ch = *cp++ ) ssym[ch]=ch ;
-
- set_type() ;
-
- maxpseudo = build_pseudo() ;
- maxop = buildopc();
-
- pass1 = sf ? TRUE : FALSE ;
- pass2 = sf ? FALSE : TRUE ;
-
- /* Main Assembler Loop */
-
- while ( pass1 || pass2 ) {
- if ( pass1 ) puts("Pass 1 : ") ;
- if ( pass2 ) puts("Pass 2 : ") ;
- lineno = 1;
-
- set_il() ;
-
- active = code_seg() ;
- hsp = hc = ht = 0 ;
- ha = he = ilc = il[active] ;
- errcnt = 0 ;
- radix = 10 ;
-
- while(( getline(ibuf)) != EOF ) {
- info = assemble() ;
- code() ;
- list() ;
- lineno++ ;
- ilc += instl ;
- } /* end while on getline(ibuf) */
-
- if ( sf ) {
- fclose(dibuf) ;
- dibuf = pass1 ? fopen(src,"r") : dibuf ;
- if( dibuf == NULL ) abort("Source Reopen ?\n") ;
- }
-
- pass1 = FALSE ;
- pass2 = pass2 ? FALSE : TRUE ;
- finish = time(NOW) ;
- printf("\t%5ld\tseconds\n",finish-start) ;
- } /* end while on pass1 || pass2 */
-
- /* Sort the Symbol Table */
-
- if ( syte ) {
- qsort(psym,syte,sizeof(int),cpmf) ;
- }
-
-
- /* Print the Symbol Table */
-
- if( !nolist ) {
- cprintf("\fSymbol Table\n\n") ;
- for ( i = 0 ; i < syte ; i++ ) {
- if ( i % 5 == 0 ) cprintf("\n") ;
- sytx = psym[i] ;
- cprintf("%-12s%04x%c ",symtab[sytx].name,
- symtab[sytx].value,
- segtype[symtab[sytx].flags & (NSEG-1)] ) ;
- }
- }
-
- cprintf("\n\n") ;
- if( errcnt > 0 ) {
- cprintf("%04d ERRORS\n",errcnt) ;
- if( nolist || lf ) printf("\n%04d ERRORS\n",errcnt) ;
- }
- else {
- cprintf(" NO ERRORS\n") ;
- if( nolist || lf ) puts("\n NO ERRORS\n") ;
- }
-
- if ( lf ) {
- putc(CPMEOF,libuf) ;
- fflush(libuf) ;
- fclose(libuf) ;
- }
-
- if ( hf ) {
- hsout() ;
- fprintf(hxbuf,":00000001FF\n") ;
- putc(CPMEOF,hxbuf) ;
- fflush(hxbuf) ;
- fclose(hxbuf) ;
- }
-
- puts("ASSEMBLY COMPLETE\n");
- finish = time(NOW) ;
- printf("\n%5ld\tseconds\n",finish-start) ;
- printf("%5ld\tlines/minute\n",lineno*60/(finish-start)) ;
- printf("%5d\tprobes\n%5d\tlookups\n",nprobe,nlook) ;
- printf("%5.2f\tprobes/lookup\n",(float)nprobe/(float)nlook) ;
- printf("%5d\tmaximum probe\n",maxprobe) ;
- nprobe = 0 ;
- for (nlook = 0 ; nlook < NHASH ; ++nlook ) {
- if( qhash[nlook] != ERROR ) ++nprobe ;
- }
- printf("%5d\thash entries\n",nprobe) ;
- printf("%5d\tpercent utilization\n",(100*nprobe)/nlook) ;
- exit();
- }
-
- cpmf(a,b)
- int *a, *b ;
- {
- return strcmp(symtab[*a].name,symtab[*b].name) ;
- }
-
- #define INFO 1
- #define NOINFO 0
-
-
- assemble()
- {
-
- setmem(ib,4,0) ; /* clear info bytes */
- esp = 0 ; /* clear error stack */
- instl = parval = valid = 0 ; /* clear length & val */
- cput = 0 ; /* clear queue */
-
- if( isin(ch,"*;\n") ) return NOINFO ;
-
- /* process labels */
-
- lbl = ERROR ;
- if ( isalpha(ch) ) {
- getsym() ;
- if ( pass1 ) {
- if ( append(id) == ERROR ) puts("Symbol Table Full\n") ;
- else { symtab[syte].value = ilc ;
- symtab[syte].flags = active ;
- psym[syte] = syte ;
- lbl= ++syte == NSYM ? (--syte , ERROR) : OK ;
- }
- }
- if( ch == ':' ) getch() ; /* swallow colons */
- }
-
- getsym() ;
- if( sym != IDENT ) return NOINFO ;
-
- /*
- search pseudo operation table
- use index in case statement to determine action
- */
- i = 0 ; k = maxpseudo - 1 ;
- do {
- j = ( i + k ) / 2 ;
- mcc = sscmp(id,pseudo[j]) ;
- if( mcc <= 0 ) k = j - 1 ;
- if( mcc >= 0 ) i = j + 1 ;
- } while( i <= k ) ;
-
- if ( i - 1 > k ) {
- j = pj[j] ;
- return (*ppo[j])() ;
- }
-
- i = 0 ; k = maxop - 1 ;
- do {
- j = ( i + k ) / 2 ;
- mcc = sscmp(id,pc[j]) ;
- if( mcc <= 0 ) k = j - 1 ;
- if( mcc >= 0 ) i = j + 1 ;
- } while( i <= k ) ;
-
- if ( i - 1 > k ) {
- while ( isin(ch," \t") ) getch() ;
- mcc = cc - 1 ;
- for ( k = px[j] ; k < px[j+1] ; ++k ) {
- valid = (*pp[k])() ;
- if( valid ) break ;
- else { iptr = &ibuf[cc=mcc] ; getch() ; }
- }
- valid ? TRUE : push('M') ;
- }
- else push('O') ;
- return INFO ;
- }
-
- code()
- {
- if ( pass1 || !info ) return ;
- if ( !hf ) return ;
- if ( not_cseg(active) ) return ;
-
- /* hex string output */
-
- if ( (hsp>0) && (he != ilc) || hsp > MAXB - 1 ) {
- hsout() ;
- ha = ilc ;
- }
-
- for ( k = 0 ; k < instl ; k++ ) {
- hs[hsp++] = ib[k] ;
- hc += ib[k] ;
- hc &= 0xFF ;
- if( hsp > MAXB-1 ) {
- hsout() ;
- ha += MAXB ;
- }
- }
- he = ilc + instl ;
- return ;
- }
-
- list()
- {
- if ( pass1 || nolist ) return ;
- lnspp -= esp + 1 ;
- if ( lf != 0 && lnspp <= 0 ) {
- pgno++ ;
- lnspp = 55 ;
- cprintf("\fCustom Computer Consultants\t\t\t\t\t\t") ;
- cprintf("PAGE %-4d\n",pgno) ;
- cprintf("%s\n",version) ;
- cprintf("LN #\tLOC CODE\t\tSOURCE\n") ;
- }
- cprintf("%04d|\t",lineno) ;
- if( instl ) cprintf("%04x%c\t",ilc,segtype[active]) ;
- else cprintf("\t") ;
- if (info) {
- kk = ( instl <= 4 ) ? instl : 4 ;
- r = instl - kk ;
- i = ( kk <= 4 ) ? 4 - kk : 0 ;
- j = 0 ;
- while ( kk--) cprintf("%02x ",ib[j++]) ;
- while ( i-- ) cprintf(" ") ;
- cprintf("\t%s",ibuf) ;
-
- while ( r ) {
- kk = r <= 4 ? r : 4 ;
- r -= kk ;
- cprintf("\t\t") ;
- while( kk-- ) cprintf("%02x ",ib[j++]) ;
- cprintf("\n") ;
- }
- }
- else cprintf("\t\t%s",ibuf) ;
- while( ch = pop() ) {
- errcnt++ ;
- switch(ch) {
- case 'R' : cprintf("R*** RELATIVE ADDRESS RANGE\n");
- break;
-
- case 'O' : cprintf("O*** ILLEGAL OPCODE\n") ;
- break;
-
- case 'M' : cprintf("M*** ADDRESSING MODE ERROR\n");
- break;
-
- case 'S' : cprintf("S*** SYNTAX ERROR\n") ;
- break;
-
- case 'P' : cprintf("P*** ILLEGAL OPERATOR\n") ;
- break ;
-
- case 'E' : cprintf("E*** SYMBOL TABLE EMPTY\n") ;
- break;
-
- case 'U' : cprintf("U*** UNDEFINED SYMBOL\n") ;
- break ;
-
- default : cprintf("E*** ERROR MESSAGE ERROR <%02x>\n",ch) ;
- }
- }
- }
-
-
- /*
- getline -- assembles one line of input text from
- the console input or from a buffered i/o
- device.
-
- */
- getline()
- {
- iptr = sf ? fgets(ibuf,MAXLINE,dibuf) :
- strcat(gets(ibuf,MAXLINE),"\n" ) ;
- if( !iptr || *iptr == CPMEOF ) return EOF ;
- ll = strlen(ibuf) ;
- cc = 0 ;
- getch() ;
- return ll ;
- }
-
- getch()
- { ch = cc < ll ? (++cc , *iptr++) : '\n' ;
- nch = *iptr ;
- }
-
- getsym()
- {
- int k, np, rad, irad ;
- char rc ;
-
- while( isin(ch," \t") ) getch() ;
- if( (sym = ssym[ch]) == ch ) return ;
- else
- if( isdigit(ch) ) {
- sym = NUMBER ;
- rad = radix ;
- np = cc - 1 ;
- do {
- irad = rad ;
- iptr = &ibuf[cc=np] ; getch() ;
- num = 0 ;
- while( ( k = _bc(ch,rad)) != ERROR ) {
- num = num * rad + k ;
- rc = ch ; /* possible radix overide */
- getch() ;
- }
- if( isin(ch,"ABCDEF") ) { rad = 16 ; continue ; }
- if( isin(ch,"doqbhx") ) rc = ch ;
- switch(rc) {
- case 'd' : rad = 10 ; getch() ; break ;
-
- case 'o' :
- case 'q' : rad = 8 ; getch() ; break ;
-
- case 'b' : rad = 2 ; getch() ; break ;
-
- case 'h' :
- case 'x' : rad = 16 ; getch() ; break ;
- }
- } while( rad != irad ) ;
- }
- else
- if( isalpha(ch) ) {
- k = 0 ;
- do {
- if( k < AL ) id[k++] = ch ;
- getch() ;
- } while ( alphanum(ch) ) ;
- sym = IDENT ;
- if ( k >= AL ) --k ;
- id[k] = EOS ;
- }
- }
-
-
- isin(c,s)
- char c ;
- char *s ;
- {
- cp = s ;
- do { if ( c == *s++ ) return s - cp ; } while ( *s ) ;
- return FALSE ;
- }
-
-
- sscmp(s,t)
- char *s, *t ;
- {
- char c ;
-
- while ( (c = toupper(*s)) == *t ) {
- if( c == EOS ) return 0 ;
- ++s ; ++t ;
- }
- return c - *t ;
- }
-
- nomatch(s)
- char *s ;
- {
- while ( *s ) {
- if ( toupper(ch) != *s++ ) return TRUE ;
- getch() ;
- }
- return FALSE ;
- }
-
- notcomma()
- {
- if( ch != ',' ) return TRUE ;
- getch() ;
- return FALSE ;
- }
-
-
- alphanum(c)
- char c ;
- { return isalpha(c) || isdigit(c) || c == '_' ; }
-
-
- /*
- Output Processing
-
- hsout()
- cprintf()
- puts()
- */
-
- hsout()
- {
- if( hsp == 0 ) return ;
- hc += (( hsp + ( ha >> 8 ) + ha + ht ) & 0xFF ) ;
- hs[hsp] = 256 - hc ;
- fprintf(hxbuf,":%02x%04x%02x",hsp,ha,ht) ;
- for ( j=0 ; j <= hsp ; j++ )
- fprintf(hxbuf,"%02x",hs[j]) ;
- fprintf(hxbuf,"\n") ;
- hsp = hc = ht = 0 ;
-
- }
-
-
-
- cprintf(format,args)
- unsigned char *format ;
- unsigned args ;
- {
- extern int write() ;
-
- int fn ;
-
- if( nolist ) return ;
- fn = lf ? fileno(libuf) : fileno(stdout) ;
- return _fmtout(&write,fn,format,&args) ;
-
- }
-
-
- /* puts -- Replaces the version in the library
- It does not do an explicit newline */
-
- puts(s)
- char *s ;
- {
- while(*s) putchar(*s++) ;
- }
-
- /*
- Expression Analyzer
-
- eval()
- hier1()
- hier2()
- hier3()
- hier4()
- term()
- factor()
- _bc
- */
-
- eval()
- {
- int val ;
-
- val = hier1() ;
- while( sym == '|' ) {
- getch() ;
- val |= hier1() ;
- }
- return val ;
- }
-
-
- hier1()
- {
- int val ;
-
- val = hier2() ;
- while( sym == '^' ) {
- getch() ;
- val ^= hier2() ;
- }
- return val ;
- }
-
-
- hier2()
- {
- int val ;
-
- val = hier3() ;
- while( sym == '&' ) {
- getch() ;
- val &= hier3() ;
- }
- return val ;
- }
-
-
- hier3()
- {
- int val ;
-
- val = hier4() ;
- while( isin(sym,"<>") ) {
- getch() ;
- switch(sym) {
- case '<' : val <<= hier4() ;
- break ;
- case '>' : val >>= hier4() ;
- }
- }
- return val ;
- }
-
- hier4()
- {
- int val ;
-
- val = term() ;
- while( isin(sym,".+-") ) {
- getch() ;
- switch(sym) {
- case '.' :
- case '+' : val += term() ;
- break ;
- case '-' : val -= term() ;
- }
- }
- return val ;
- }
-
- term()
- {
- int val ;
-
- val = factor() ;
- while( isin(sym,"*/%") ) {
- getch() ;
- switch (sym) {
- case '*' : val *= factor() ;
- break ;
- case '/' : val /= factor() ;
- break ;
- case '%' : val %= factor() ;
- }
- }
- return val ;
- }
-
- factor()
- {
- int val, sx ;
- char sign ;
-
- val = 0 ; sign = '+' ; sytx = ERROR ;
- getsym() ;
- if( isin(sym,"+-~") ) {
- sign = sym ;
- getch() ;
- getsym() ;
- }
- if( sym == IDENT ) {
- sx = lookup(id) ;
- if( sx == NSYM ) push('U') ;
- else
- if( sx == ERROR ) push('E') ;
- else {
- val = symtab[sx].value ;
- sytx = sx ;
- getsym() ;
- }
- }
- else
- if( sym == NUMBER ) {
- val = num ;
- getsym() ;
- }
- else
- if( sym == '(' ) {
- getch() ;
- val = eval() ;
- if( sym == ')' ) { getch() ; getsym() ; }
- else push('S') ;
- }
- else
- if( sym == '$' ) {
- val = ilc ;
- getch() ;
- getsym() ;
- }
- else
- if( sym == '\'' ) {
- getch() ;
- val = ch & 0xFF ;
- getch() ;
- if( ch == '\'' ) { getch() ; getsym() ; }
- else push('S') ;
- }
- else push('S') ;
-
- switch(sign) {
- case '-' : val = -val ;
- break ;
- case '~' : val = ~val ;
-
- default : break ;
- }
- return val ;
- }
-
- _bc(c,b)
- char c, b ;
- {
- if(isalpha(c = toupper(c))) c -= 55 ;
- else if(isdigit(c)) c -= 0x30 ;
- else return ERROR ;
- if(c > b-1) return ERROR ;
- else return c ;
- }
-
- /*
- Symbol Table Routines
-
- append() adds a new symbol to the table
- lookup() checks the table for a symbol
- */
-
- hash(s,l)
- unsigned char *s ;
- unsigned int l ;
- {
- unsigned char c ;
-
- if ( l == 0 ) l = strlen(s) ;
- c = ( *s + *(s+l-1) ) >> 1 ;
- return (( c * HP1 + l * HP2 ) & (NHASH-1));
- }
-
- append(s)
- char *s ;
- {
- int h, q ;
- int l ;
-
- if ( syte == NSYM ) return ERROR ;
- l = 1 + strlen(s) ;
- symtab[syte].name = sbrk(l) ;
- strcpy(symtab[syte].name , s ) ;
- symtab[syte].flags = '\0' ;
- symtab[syte].value = 0 ;
- symtab[syte].link = ERROR ;
-
- h = hash(s,l-1) ;
- q = qhash[h] ;
- if ( q == ERROR ) qhash[h] = syte ;
- else {
- while( symtab[q].link != ERROR ) q = symtab[q].link ;
- symtab[q].link = syte ;
- }
- return OK ;
- }
-
- lookup(s)
- char *s ;
- {
- int q, m ;
-
- m = 0 ;
- if ( syte == 0 ) return ERROR ; /* ST EMPTY */
- ++nlook ;
- q = qhash[hash(s,0)] ;
- while( q != ERROR ) {
- ++nprobe ; ++m ;
- if( m > maxprobe ) maxprobe = m ;
- if( strcmp(symtab[q].name,s) == 0 ) return q ;
- q = symtab[q].link ;
- }
- return NSYM ; /* Not Found */
- }
-
-
- /* Error Processing
-
- abort()
- push()
- pop()
- */
-
- abort(s)
- char *s ;
-
- { puts(s) ; exit() ; }
-
-
- char push(c)
- char c;
- {
- if( esp < 25 ) return (errstk[esp++] = c);
- return '\0';
- }
-
- char pop()
- {
- if( esp > 0 ) return (errstk[--esp]);
- return '\0';
- }
-
-
- /*
- End of UASM.C
- */
-
-
-
-